package com.lmaos.basetools.timer;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.NodeList;

import com.lmaos.allcontrol.beancontrol.class_.ClassUtils;
import com.lmaos.allcontrol.beancontrol.entity_.LMClassParam;
import com.lmaos.allcontrol.beancontrol.method_.MethodUtils;
import com.lmaos.allcontrol.beancontrol.utils_.ObjUtils;
import com.lmaos.basetools.base.SParamMap;
import com.lmaos.basetools.sText.XmlUtils;

public class TimerStart {
	/**
	 * 说明：获得定时任务的类		<br>
	 * 时间：2017年6月20日 上午11:22:59
	 *
	 * @param xml
	 * @return
	 */
	public static List<BaseTimerBean> getTimerObjectByConfig(String xml){
		List<BaseTimerBean> timerObjects = new ArrayList<BaseTimerBean>();
		try {
			Document doc = XmlUtils.getDoucmentByClassPath(xml, TimerStart.class.getClassLoader());
			List<Document> includeDocs = XmlUtils.getIncludeDocument(doc, TimerStart.class.getClassLoader(), "include", "file");
			for (Document document : includeDocs) {
				Element root = document.getDocumentElement();
				NodeList timerNodes = root.getElementsByTagName("timer");
				for (int i = 0; i < timerNodes.getLength(); i++) {
					Element timerNode = XmlUtils.getElement(timerNodes, i);
					if(timerNode!=null){
						String className = timerNode.getAttribute("class");
						Object timerObject = ClassUtils.getObject(className);
						if(timerObject!=null){
							BaseTimerConfigGroup configGroup = getBaseTimerConfigGroupByXmlNode(timerNode);
							timerObjects.add(new BaseTimerBean(timerObject, configGroup));
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return timerObjects;
	}
	/**
	 * 说明：获得当前节点下的一组配置		<br>
	 * 时间：2017年6月26日 上午10:01:33
	 *
	 * @param node
	 * @return
	 */
	public static BaseTimerConfigGroup getBaseTimerConfigGroupByXmlNode(Element node){
		BaseTimerConfigGroup baseTimerConfigGroup = new BaseTimerConfigGroup(node.getTextContent());
		NodeList nodeContents = node.getChildNodes();
		for (int i = 0; i < nodeContents.getLength(); i++) {
			Element tagNode = XmlUtils.getElement(nodeContents, i);
			if(tagNode!=null){
				String tagName = tagNode.getTagName();
				String content = tagNode.getTextContent();
				BaseTimerConfig baseTimerConfig = new BaseTimerConfig(tagName, content, tagNode);
				NamedNodeMap namedNodeMap = tagNode.getAttributes();
				for (int j = 0; j < namedNodeMap.getLength(); j++) {
					Attr attr = (Attr) namedNodeMap.item(j);
					baseTimerConfig.put(attr.getName(), attr.getValue());
				}
				baseTimerConfigGroup.add(baseTimerConfig);
			}
		}
		return baseTimerConfigGroup;
	}
	
	private volatile static SParamMap paramMap = new SParamMap();
	public static void startBaseTimer(String xml){
		List<BaseTimerBean> timerObjects = getTimerObjectByConfig(xml);
		startBaseTimer(timerObjects);
		
	}
	
	public static void startBaseTimer(List<BaseTimerBean> timerObjects){
		for (BaseTimerBean timerObject : timerObjects) {
			startBaseTimer(timerObject.getTimerObject(),timerObject.getConfigGroup());
		}
	}
	public static void startBaseTimer(Object timerObject, BaseTimerConfigGroup beanTimerConfigGroup){
		List<Method> init_methods = MethodUtils.indexMethodByAnnotation(timerObject.getClass(), BaseTimerInit.class);
		init_sort(init_methods);
		for (Method method : init_methods) {
			try {
				BaseTimerInit baseTimerInit = method.getAnnotation(BaseTimerInit.class);
				System.out.println("init name->"+baseTimerInit.name()+",des->"+baseTimerInit.des());
				LMClassParam classParam = new LMClassParam();
				classParam.put(beanTimerConfigGroup);
				classParam.put(paramMap);
				ObjUtils.executeMethod(timerObject, method, classParam);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		List<Method> timermethods = MethodUtils.indexMethodByAnnotation(timerObject.getClass(), BaseTimer.class);
		for (Method method : timermethods) {
			BaseTimerThread t = new BaseTimerThread(paramMap, method, timerObject,beanTimerConfigGroup);
			t.start();
		}
	}
	private static void init_sort(List<Method> init_methods){
		Collections.sort(init_methods, new Comparator<Method>(){

			@Override
			public int compare(Method o1, Method o2) {
				BaseTimerInit i1 = o1.getAnnotation(BaseTimerInit.class);
				BaseTimerInit i2 = o2.getAnnotation(BaseTimerInit.class);
				int sort1 = i1!=null?i1.sort():0;
				int sort2 = i2!=null?i2.sort():0;
				return sort1-sort2;
			}
			
		});
	}
	public static void main(String[] args) {
		startBaseTimer("timer.xml");
	}
	
	public static SParamMap getParamMap() {
		return paramMap;
	}
	public static void setParamMap(SParamMap paramMap) {
		if(TimerStart.paramMap == null){
			TimerStart.paramMap = paramMap;
		}else{
			TimerStart.paramMap.putAll(paramMap);
		}
	}
}
